﻿using System;
using System.Collections.Generic;
using System.Text;

namespace KDG.Sys
{
    public class FileSizeFormatProvider : IFormatProvider, ICustomFormatter
    {
        public object GetFormat(Type formatType)
        {
            if (formatType == typeof(ICustomFormatter)) return this;
            return null;
        }

        private const string fileSizeFormat = "fs";
        private const Decimal OneKiloByte = 1024M;
        private const Decimal OneMegaByte = OneKiloByte * 1024M;
        private const Decimal OneGigaByte = OneMegaByte * 1024M;

        public string Format(string format, object arg, IFormatProvider formatProvider)
        {

            if (arg is string)
            {
                return defaultFormat(format, arg, formatProvider);
            }

            Decimal size;

            try
            {
                size = Convert.ToDecimal(arg);
            }
            catch (InvalidCastException)
            {
                return defaultFormat(format, arg, formatProvider);
            }

            string suffix;
            if (format == null)
            {
                if (size > OneGigaByte) { size /= OneGigaByte; suffix = " GB"; }
                else if (size > OneMegaByte) { size /= OneMegaByte; suffix = " MB"; }
                else if (size > OneKiloByte) { size /= OneKiloByte; suffix = " kB"; }
                else { suffix = " B"; }
            }
            else
            {
                switch (format)
                {
                    case "GB": size /= OneGigaByte; suffix = " GB"; break;
                    case "MB": size /= OneMegaByte; suffix = " MB"; break;
                    case "kB": size /= OneKiloByte; suffix = " kB"; break;
                    default: suffix = " B"; break;
                }
            }

            //string precision = format.Substring(2);
            //if (String.IsNullOrEmpty(precision)) precision = "2";
            //return String.Format("{0:N" + precision + "}{1}", size, suffix);

            return String.Format("{0:N2}{1}", size, suffix);
        }

        private static string defaultFormat(string format, object arg, IFormatProvider formatProvider)
        {
            IFormattable formattableArg = arg as IFormattable;
            if (formattableArg != null)
            {
                return formattableArg.ToString(format, formatProvider);
            }
            return arg.ToString();
        }
    }
}
